using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.DataAccess.SPI;
using T.FAS.Runtime.DataAccess.SQLDom;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.Common;

namespace T.FAS.Runtime.DataAccess.Engine
{
    /// <summary>
    /// 数据上下文
    /// </summary>
    public class DataContext
    {
        private Dictionary<string, List<DataContextItem>> data;

        /// <summary>
        /// 数据字典, key: CNO.id; value:
        /// </summary>
        public Dictionary<string, List<DataContextItem>> Data
        {
            get
            {
                if (data == null)
                    data = new Dictionary<string, List<DataContextItem>>();

                return data;
            }
        }

        /// <summary>
        /// 主节点实例
        /// </summary>
        public CompositeNodeObject MainCompositeNodeObject { get; set; }

        /// <summary>
        /// 入口点，记录指定非Root CompositeNodeObject节点的调用方式
        /// </summary>
        public CompositeNodeObject EntryCompositeNodeObject { get; set; }

        /// <summary>
        /// 查询过滤条件
        /// </summary>
        public QueryFilter QueryFilter { get; set; }
         
        /// <summary>
        /// 当前的数据索引
        /// </summary>
        public int CurrentDataIndex { get; set; }

        /// <summary>
        /// 获取当前数据上下文项
        /// </summary>
        /// <param name="modelObjectID">领域对象ID</param>
        /// <returns>当前数据上下文项</returns>
        public DataContextItem GetCurrentDataContextItem(string modelObjectID)
        {
            //如果当前环境不包含当前节点数据或该数据为空则为null
            if (!Data.ContainsKey(modelObjectID) || Data[modelObjectID].Count == 0) return null;
            if (CurrentDataIndex > Data[modelObjectID].Count - 1)
                throw new FasException(DataAccessErrorCode.DataContext.Error, string.Format(CommonStringClassEngine.DataContext_GetCurrentDataContextItem,CurrentDataIndex,Data[modelObjectID].Count));
            return Data[modelObjectID][CurrentDataIndex];
        }

        /// <summary>
        /// 获取当前上下文中的主键数据
        /// </summary>
        /// <returns>当前上下文中的主键数据</returns>
        public IDictionary<string, object> GetCurrentPrimaryKeyData()
        {
            IDictionary<string, object> pkData = null;

            foreach (var dataItem in data)
            {
                pkData = dataItem.Value[CurrentDataIndex].PrimaryKeyData;
                if (pkData != null && pkData.Count() > 0)
                    return pkData;
            }

            return pkData;
        }
         
        /// <summary>
        /// 获取当前上下文中指定节点的主键数据。删除时，可以只删除指定节点及其子节点的数据
        /// </summary>
        /// <returns>当前上下文中的主键数据</returns>
        public IDictionary<string, object> GetCurrentNodePrimaryKeyData(string CompositeNodeObjectId)
        {
            IDictionary<string, object> pkData = new Dictionary<string, object>();
            if(data.Keys.Contains(CompositeNodeObjectId))
                pkData = data[CompositeNodeObjectId][CurrentDataIndex].PrimaryKeyData;
            return pkData;
        }
         
        /// <summary>
        /// 获取当前上下文中入口节点的主键数据。删除时，可以只删除指定节点及其子节点的数据
        /// </summary>
        /// <returns>当前上下文中的主键数据</returns>
        public IDictionary<string, object> GetEntryNodePrimaryKeyData()
        {
            IDictionary<string, object> pkData = new Dictionary<string, object>();
            if (data.Keys.Contains(EntryCompositeNodeObject.ID))
                pkData = data[EntryCompositeNodeObject.ID][CurrentDataIndex].PrimaryKeyData;
            return pkData;
        }

        /// <summary>
        /// 重置当前的数据索引
        /// </summary>
        public void ResetCurrentDataIndex()
        {
            CurrentDataIndex = 0;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="modelObjectID"></param>
        /// <param name="dataItems"></param>
        public void Add(string modelObjectID, List<DataContextItem> dataItems)
        {
            //如果字典中已有Key，则插入到List中而不是覆盖。
            if (Data.ContainsKey(modelObjectID))
                Data[modelObjectID].AddRange(dataItems);
            else
                Data[modelObjectID] = dataItems;
        }

        public void Remove(string modelObjectID)
        {
            if (Data.ContainsKey(modelObjectID))
            {
                this.Data.Remove(modelObjectID);
            }
        }
    }
}
